package com.wang.view.minorframe;

import com.wang.bean.Book;
import com.wang.bean.LendInfo;
import com.wang.service.BookService;
import com.wang.service.LendInfoService;
import com.wang.service.TypeService;
import com.wang.service.impl.BookServiceImpl;
import com.wang.service.impl.LendInfoServiceImpl;
import com.wang.service.impl.TypeServiceImpl;
import com.wang.view.baseview.MinorFrame;

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Date;
import java.util.*;
import java.util.List;

/**
 * 借阅图书界面
 */
public class LendBookFrame extends MinorFrame {

    // 定义一个私有的JTable对象，用于显示图书数据
    private JTable table;

    // 定义一个DefaultTableModel对象，用于管理表格中的数据
    private DefaultTableModel tdm;

    // 创建一个BookService的实例，用于处理图书相关业务逻辑
    private final BookService bookService = new BookServiceImpl();

    // 创建一个TypeService的实例，用于处理类型相关业务逻辑
    private final TypeService typeService = new TypeServiceImpl();

    // 创建一个LendInfoService的实例，用于处理借阅信息相关业务逻辑
    private final LendInfoService lendInfoService = new LendInfoServiceImpl();

    // 定义两个JRadioButton对象，用于选择查询条件
    private  JRadioButton jrb1, jrb2;

    // 定义两个JComboBox对象，用于选择查询条件或分类
    private  JComboBox<String> jcb1, jcb2;

    // 定义多个JTextField对象，用于输入查询关键字或其他信息
    private  JTextField jtf1, jtf2, jtf3, jtf4, jtf5, jtf6;

    // 定义一个JTextArea对象，用于显示详细信息或备注
    private  JTextArea jta;

    public LendBookFrame(String username) {
        super("图书借阅", 800, 650);
        initFrame(username);
    }

    private void initFrame(String username){
        JPanel jp = new JPanel() {
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawLine(120, 330, getWidth() - 50, 330);
                g.drawLine(50, 580, getWidth() - 50, 580);
                g.drawLine(50, 330, 50, 580);
                g.drawLine(getWidth() - 50, 330, getWidth() - 50, 580);
                g.drawLine(120, 30, getWidth() - 50, 30);
                g.drawLine(50, 100, getWidth() - 50, 100);
                g.drawLine(50, 30, 50, 100);
                g.drawLine(getWidth() - 50, 30, getWidth() - 50, 100);
            }
        };
        jp.setLayout(null);

        initTable();

        JLabel jl1 = new JLabel("搜索条件");
        JLabel jl2 = new JLabel("图书名称：");
        JLabel jl3 = new JLabel("图书作者：");
        JLabel jl4 = new JLabel("图书类别：");
        JLabel jl5 = new JLabel("表单操作");
        JLabel jl6 = new JLabel("图书名称：");
        JLabel jl7 = new JLabel("图书作者：");
        JLabel jl8 = new JLabel("作者性别：");
        JLabel jl9 = new JLabel("图书价格：");
        JLabel jl10 = new JLabel("图书库存：");
        JLabel jl11 = new JLabel("图书类别：");
        JLabel jl12 = new JLabel("图书描述：");
        jtf1 = new JTextField();
        jtf2 = new JTextField();
        jtf3 = new JTextField();
        jtf4 = new JTextField();
        jtf5 = new JTextField();
        jtf6 = new JTextField();
        jta = new JTextArea(20, 20);
        jta.setLineWrap(true);
        JScrollPane j = new JScrollPane();
        jrb1 = new JRadioButton("男");
        jrb2 = new JRadioButton("女");
        ButtonGroup bg = new ButtonGroup();
        bg.add(jrb1);
        bg.add(jrb2);
        jrb1.setSelected(true);
        jcb1 = new JComboBox<>();
        jcb2 = new JComboBox<>();
        JButton jb1 = new JButton("查询");
        JButton jb2 = new JButton("借阅");
        JScrollPane jsp = new JScrollPane(table);

        jtf3.setEnabled(false);
        jtf4.setEnabled(false);
        jtf5.setEnabled(false);
        jtf6.setEnabled(false);
        jta.setEnabled(false);
        jcb2.setEnabled(false);
        jrb1.setEnabled(false);
        jrb2.setEnabled(false);

        jl1.setBounds(57, 20, 70, 20);
        jl2.setBounds(60, 55, 70, 20);
        jl3.setBounds(237, 55, 70, 20);
        jl4.setBounds(385, 55, 70, 20);
        jl5.setBounds(57, 320, 70, 20);
        jtf1.setBounds(125, 57, 100, 20);
        jtf2.setBounds(302, 57, 70, 20);
        jb1.setBounds(657, 42, 60, 20);
        jb2.setBounds(657, 72, 60, 20);
        jsp.setBounds(50, 125, 686, 180);
        jcb1.setBounds(455, 57, 180, 20);
        jcb2.setBounds(510, 397, 180, 20);
        jl6.setBounds(100, 355, 70, 20);
        jl7.setBounds(310, 355, 70, 20);
        jl8.setBounds(520, 355, 70, 20);
        jtf3.setBounds(170, 357, 130, 20);
        jtf4.setBounds(380, 357, 130, 20);
        jrb1.setBounds(590, 355, 40, 20);
        jrb2.setBounds(640, 355, 40, 20);
        jl9.setBounds(100, 395, 70, 20);
        jl10.setBounds(270, 395, 70, 20);
        jl11.setBounds(440, 395, 70, 20);
        jtf5.setBounds(170, 397, 90, 20);
        jtf6.setBounds(340, 397, 90, 20);
        jl12.setBounds(100, 438, 70, 20);
        j.setBounds(170, 440, 522, 120);

        fillBookTypeName();

        j.setViewportView(jta);
        jp.add(jl1);
        jp.add(jl2);
        jp.add(jl3);
        jp.add(jl4);
        jp.add(jl5);
        jp.add(jl6);
        jp.add(jl7);
        jp.add(jl8);
        jp.add(jl9);
        jp.add(jl10);
        jp.add(jl11);
        jp.add(jl12);
        jp.add(jtf1);
        jp.add(jtf2);
        jp.add(jtf3);
        jp.add(jtf4);
        jp.add(jtf5);
        jp.add(jtf6);
        jp.add(j);
        jp.add(jrb1);
        jp.add(jrb2);
        jp.add(jcb1);
        jp.add(jcb2);
        jp.add(jb1);
        jp.add(jb2);
        jp.add(jsp);

        table.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                bookMousePressed();
            }
        });

        jb1.addActionListener(this::searchAction);
        jb2.addActionListener(actionEvent ->lendAction(username));

        setContentPane(jp);
    }

    /**
     * 实现搜索功能，根据用户输入的书名、作者和类型进行模糊搜索。
     * 当没有输入任何搜索条件或搜索结果为空时，给出相应提示。
     * 搜索结果会在表格中选中对应的行，并在下方的文本框中显示部分搜索结果信息。
     *
     * @param e ActionEvent，触发搜索动作的事件。
     */
    //查询按钮
    private void searchAction(ActionEvent e) {
        // 清除表格中的选中行
        //表格先清空选择
        table.removeRowSelectionInterval(0, table.getRowCount() - 1);

        // 获取并处理输入的搜索条件
        // 模糊查找
        String strOfName = jtf1.getText().trim();
        String strOfAuthor = jtf2.getText().trim();
        String strOfType = (String) jcb1.getSelectedItem();

        // 如果所有条件都为空，则提示用户输入搜索信息
        if ("".equals(strOfName) && "".equals(strOfAuthor) && "请选择……".equals(strOfType)) {
            JOptionPane.showMessageDialog(null, "请输入查询信息！", "警告", JOptionPane.WARNING_MESSAGE);
            return;
        }

        // 初始化搜索结果列表
        List<Book> list = new ArrayList<>();

        // 根据书名、作者、类型分别进行搜索，并将结果合并到列表中
        if (!"".equals(strOfName)) {
            list.addAll(bookService.getBookListByBookName(strOfName));
        }
        if (!"".equals(strOfAuthor)) {
            list.addAll(bookService.getBookListByAuthor(strOfAuthor));
        }
        if (!"".equals(strOfType)) {
            list.addAll(bookService.getBookListByTypeName(strOfType));
        }

        // 如果搜索结果为空，则提示用户
        if (list.size() == 0) {
            JOptionPane.showMessageDialog(null, "未查询到指定结果！");
            return;
        }

        // 在表格中选中搜索结果对应的行
        for (Book book : list) {
            for (int j = 0; j < tdm.getRowCount(); j++) {
                //将查询到的book根据书名得到表中行数选择得到的行数
                if (book.getBookId().equals(table.getValueAt(j, 0))) {
                    table.addRowSelectionInterval(j, j);
                    break;
                }
            }
        }

        // 随机展示一个搜索结果的信息
        // 随机展出一个查询到的book对象的信息
        Book book = list.get((int) ((Math.random() * 100) % list.size()));
        jtf3.setText(book.getBookName());
        jtf4.setText(book.getAuthor());
        jtf5.setText(String.valueOf(book.getPrice()));
        jtf6.setText(String.valueOf(book.getBookNum()));
        jta.setText(book.getBookDesc());
        if ("男".equals(book.getGender())) {
            jrb1.setSelected(true);
        } else {
            jrb2.setSelected(true);
        }
        jcb2.setSelectedItem(book.getTypeName());

        // 提示用户搜索到的结果数量
        JOptionPane.showMessageDialog(null, "共查询到" + table.getSelectedRowCount() + "条结果！");
    }


    /**
     * 处理图书借阅操作。
     * 当用户尝试借阅图书时，此方法将检查所选图书是否满足借阅条件，例如库存数量足够，并提示用户确认借阅。
     * 如果借阅操作被确认，将更新图书库存，并记录借阅信息。
     *
     * @param username 当前操作用户的用户名，用于记录借阅信息。
     */
    //借阅按钮
    private void lendAction(String username) {
        // 检查是否选择了多本图书，因为系统不支持同时借阅多本。
        if (table.getSelectedRowCount() > 1) {
            JOptionPane.showMessageDialog(null, "不支持同时借阅多本图书！", "警告", JOptionPane.WARNING_MESSAGE);
            return;
        }

        // 获取选中的图书行，如果没有选中任何行，则提示用户选择待借阅的图书。
        //获取选中行
        int row = table.getSelectedRow();
        if (row == - 1) { //没有选择
            JOptionPane.showMessageDialog(null, "请选择待借阅图书！", "警告", JOptionPane.WARNING_MESSAGE);
            return;
        }

        // 检查所选图书的库存数量，如果为0，则提示用户该书无库存。
        if (Integer.parseInt(String.valueOf(table.getValueAt(row, 5))) == 0) {
            JOptionPane.showMessageDialog(null, "该书无库存！", "警告", JOptionPane.WARNING_MESSAGE);
            return;
        }

        // 提示用户确认借阅操作，如果用户取消，则返回。
        int isFlag = JOptionPane.showConfirmDialog(null, "是否借阅？");
        if (isFlag > 0) {
            return;
        }

        // 获取所选图书的名称，并执行借阅操作，减少图书库存。
        String bookName = (String) table.getValueAt(row, 1);
        //执行借阅
        bookService.lendBook(bookName); //库存减一

        // 记录借阅信息，包括图书名称、用户名、借阅时间等。
        //填入借阅信息
        lendInfoService.lendBook(new LendInfo(null, bookName, username, new Date(System.currentTimeMillis()), "未归还"));

        // 更新图书库存数量，并在界面上显示更新后的数量。
        // 更新数量
        Long newNum = (Long) table.getValueAt(row, 5) - 1;
        table.setValueAt(newNum, row, 5);
        jtf6.setText(String.valueOf(newNum));

        // 提示用户借阅操作成功。
        JOptionPane.showMessageDialog(null, "借阅成功！");
    }


    //监听鼠标点击事件
    private void bookMousePressed() {
        int row = table.getSelectedRow();
        jtf3.setText(String.valueOf(table.getValueAt(row, 1)));
        jtf4.setText(String.valueOf(table.getValueAt(row, 2)));
        jtf5.setText(String.valueOf(table.getValueAt(row, 4)));
        jtf6.setText(String.valueOf(table.getValueAt(row, 5)));
        String gender = String.valueOf(table.getValueAt(row, 3));
        if ("男".equals(gender)) {
            jrb1.setSelected(true);
        } else {
            jrb2.setSelected(true);
        }
        String typeName = String.valueOf(table.getValueAt(row, 6));
        jcb2.setSelectedItem(typeName);
        jta.setText(String.valueOf(table.getValueAt(row, 7)));
    }

    //初始化表格
    private void initTable() {
        //创建表格
        String[] columnNames = {"编号", "图书名称", "作者", "作者性别", "图书价格","图书库存", "图书类别", "图书描述"};
        Object[][] rowType = bookService.getAllBookToArray();
        tdm = new DefaultTableModel(rowType, columnNames);
        table = new JTable(tdm) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return false; //不可编辑，但可以选择
            }
        };
        //
        DefaultTableCellRenderer dtcr = new DefaultTableCellRenderer();//单元格渲染器
        dtcr.setHorizontalAlignment(JLabel.CENTER);//居中显示
        table.setDefaultRenderer(Object.class, dtcr);//设置渲染器t

        table.getColumnModel().getColumn(0).setPreferredWidth(30);
        table.getColumnModel().getColumn(1).setPreferredWidth(100);
        table.getColumnModel().getColumn(2).setPreferredWidth(100);
        table.getColumnModel().getColumn(3).setPreferredWidth(50);
        table.getColumnModel().getColumn(4).setPreferredWidth(50);
        table.getColumnModel().getColumn(5).setPreferredWidth(50);
        table.getColumnModel().getColumn(6).setPreferredWidth(100);
        table.getColumnModel().getColumn(7).setPreferredWidth(180);

        table.getTableHeader().setReorderingAllowed(false); //不可改变列的位置
    }

    //初始化类别下拉菜单
    private void fillBookTypeName() {
        jcb1.addItem("请选择……");
        jcb2.addItem("请选择……");
        List<com.wang.bean.Type> types = typeService.getAllTypeToList();
        for (com.wang.bean.Type type : types) {
            jcb1.addItem(type.getTypeName());
            jcb2.addItem(type.getTypeName());
        }
    }
}
